import json
from pathlib import Path
from typing import Any, Dict, Optional


class UserConfigError(RuntimeError):
    """Raised when the user configuration file is missing or invalid."""


_CONFIG_CACHE: Optional[Dict[str, Any]] = None
_CONFIG_PATH = Path(__file__).resolve().parents[1] / "config" / "userConfig.json"


def _load_config_from_disk() -> Dict[str, Any]:
    if not _CONFIG_PATH.exists():
        raise UserConfigError(
            f"Cannot find configuration file at {_CONFIG_PATH}. "
            "Please create core/config/userConfig.json."
        )

    try:
        with _CONFIG_PATH.open("r", encoding="utf-8") as config_file:
            return json.load(config_file)
    except json.JSONDecodeError as exc:
        raise UserConfigError(
            f"Failed to parse configuration file at {_CONFIG_PATH}."
        ) from exc


def get_user_config() -> Dict[str, Any]:
    """
    Returns the cached configuration dictionary loaded from userConfig.json.
    """
    global _CONFIG_CACHE
    if _CONFIG_CACHE is None:
        _CONFIG_CACHE = _load_config_from_disk()
    return _CONFIG_CACHE


def get_config_section(section: str) -> Dict[str, Any]:
    """
    Helper that retrieves a specific section from the configuration.
    Returns an empty dict if the section does not exist.
    """
    return get_user_config().get(section, {})
